<?php

namespace app\service;

use Exception;
use GuzzleHttp\Client;

class DouyinService
{
    private $config;
    private $client;

    public function __construct()
    {
        $this->config = config('oauth.douyin');
        $this->client = new Client([
            'timeout' => 10,
            'verify' => false,
        ]);
    }

    /**
     * 获取用户信息
     */
    public function getUserInfo($code)
    {
        // 1. 通过code获取access_token
        $tokenData = $this->getAccessToken($code);

        // 2. 通过access_token获取用户信息
        $userInfo = $this->getUserInfoByToken($tokenData['access_token'], $tokenData['open_id']);

        return [
            'openid' => $tokenData['open_id'],
            'unionid' => $userInfo['union_id'] ?? '',
            'nickname' => $userInfo['nickname'] ?? '',
            'avatar' => $userInfo['avatar'] ?? '',
            'access_token' => $tokenData['access_token'],
            'refresh_token' => $tokenData['refresh_token'],
            'expires_at' => date('Y-m-d H:i:s', time() + $tokenData['expires_in']),
            'platform' => 'douyin',
            'extra_data' => [
                'gender' => $userInfo['gender'] ?? 0,
                'city' => $userInfo['city'] ?? '',
                'province' => $userInfo['province'] ?? '',
                'country' => $userInfo['country'] ?? '',
            ]
        ];
    }

    /**
     * 通过code获取access_token
     */
    private function getAccessToken($code)
    {
        $response = $this->client->post('https://open.douyin.com/oauth/access_token/', [
            'form_params' => [
                'client_key' => $this->config['app_id'],
                'client_secret' => $this->config['app_secret'],
                'code' => $code,
                'grant_type' => 'authorization_code',
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['error_code'])) {
            throw new Exception('抖音授权失败: ' . ($result['description'] ?? '未知错误'));
        }

        if ($result['data']['error_code'] !== 0) {
            throw new Exception('抖音授权失败: ' . ($result['data']['description'] ?? '未知错误'));
        }

        return $result['data'];
    }

    /**
     * 通过access_token获取用户信息
     */
    private function getUserInfoByToken($accessToken, $openId)
    {
        $response = $this->client->get('https://open.douyin.com/oauth/userinfo/', [
            'query' => [
                'access_token' => $accessToken,
                'open_id' => $openId,
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['error_code'])) {
            throw new Exception('获取用户信息失败: ' . ($result['description'] ?? '未知错误'));
        }

        if ($result['data']['error_code'] !== 0) {
            throw new Exception('获取用户信息失败: ' . ($result['data']['description'] ?? '未知错误'));
        }

        return $result['data'];
    }

    /**
     * 刷新access_token
     */
    public function refreshAccessToken($refreshToken)
    {
        $response = $this->client->post('https://open.douyin.com/oauth/refresh_token/', [
            'form_params' => [
                'client_key' => $this->config['app_id'],
                'refresh_token' => $refreshToken,
                'grant_type' => 'refresh_token',
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['error_code'])) {
            throw new Exception('刷新Token失败: ' . ($result['description'] ?? '未知错误'));
        }

        if ($result['data']['error_code'] !== 0) {
            throw new Exception('刷新Token失败: ' . ($result['data']['description'] ?? '未知错误'));
        }

        return $result['data'];
    }

    /**
     * 获取抖音小程序码
     */
    public function getMiniQrcode($accessToken, $appId, $path = '', $width = 430)
    {
        $response = $this->client->post('https://open.douyin.com/api/apps/qrcode/', [
            'json' => [
                'access_token' => $accessToken,
                'app_id' => $appId,
                'path' => $path,
                'width' => $width,
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['error_code'])) {
            throw new Exception('生成小程序码失败: ' . ($result['description'] ?? '未知错误'));
        }

        return $result['data']['qrcode_url'];
    }

    /**
     * 验证access_token是否有效
     */
    public function checkAccessToken($accessToken, $openId)
    {
        try {
            $this->getUserInfoByToken($accessToken, $openId);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 获取抖音小程序access_token（用于接口调用）
     */
    public function getClientToken()
    {
        $response = $this->client->post('https://open.douyin.com/oauth/client_token/', [
            'form_params' => [
                'client_key' => $this->config['app_id'],
                'client_secret' => $this->config['app_secret'],
                'grant_type' => 'client_credential',
            ]
        ]);

        $result = json_decode($response->getBody()->getContents(), true);

        if (isset($result['error_code'])) {
            throw new Exception('获取client_token失败: ' . ($result['description'] ?? '未知错误'));
        }

        if ($result['data']['error_code'] !== 0) {
            throw new Exception('获取client_token失败: ' . ($result['data']['description'] ?? '未知错误'));
        }

        return $result['data']['access_token'];
    }
}